#ifndef COMMUNICATION_H
#define COMMUNICATION_H

#include <QVector>

// 通信命令定义
enum CommunicationCommand
{
    NONE,
    KEY_OP,
    ADD_GOODS,
    ADD_FREQUSED_GOODS,
    REMOVE_GOODS,
    REMOVE_FSREQUSED_GOODS,
    SET_PRICE,
    SET_TTS_VOLUMN,
    SET_TTS_RATE,
    GOODS_SIZE,
    FREQUSED_GOODS_SIZE,
    GOODS_INFORMATION,
    FREQUSED_GOODS_INFORMATION,
    SHOW_INFORMATION,
    SPEECH_INFORMATION,
    REVER_ROW,
    FREQUSED_GOODS_OK,
    ADD_GOODS_OK,
    ADD_FREQUSED_GOODS_OK,
    REMOVE_GOODS_OK,
    REMOVE_FREQUSED_GODOS_OK,
    TRANSACTION_RECORD,
    CLEAR_AMOUNT,
    POWERSAVING,
};

// 商品类
struct Goods
{
    unsigned char name[12] = { 0 };
    float price = 0.0;
};

// 蓝牙通信队列类
class SocketBuf
{
    static constexpr int BUFSIZE = 65535;

public:
    SocketBuf(int size = BUFSIZE);
    int size() const;
    void init();
    unsigned char peek(int pos) const;
    unsigned char read();
    void write(unsigned char dat);
    unsigned char moveToHead();

private:
    QVector<unsigned char> buf;
    int head, tail;
};

bool readN(SocketBuf* socketBuf, unsigned char dat[], int n);
QByteArray formatSendData(CommunicationCommand command, unsigned char dat[], int n);
CommunicationCommand formatReadData(SocketBuf* socketBuf, unsigned char dat[]);

inline SocketBuf::SocketBuf(int size)
    : buf(size)
    , head(0)
    , tail(0)
{
}

inline int SocketBuf::size() const
{
    if (tail < head)
    {
        return tail + (BUFSIZE - head);
    }
    return tail - head;
}

inline void SocketBuf::init()
{
    head = 0;
    tail = 0;
}

inline unsigned char SocketBuf::peek(int pos) const
{
    return buf[(head + pos) & BUFSIZE];
}

inline unsigned char SocketBuf::read()
{
    unsigned char dat = buf[head++];
    head &= BUFSIZE;
    return dat;
}

inline void SocketBuf::write(unsigned char dat)
{
    buf[tail++] = dat;
    tail &= BUFSIZE;
}

inline unsigned char SocketBuf::moveToHead()
{
    while (size() >= 3 && !(buf[head] == 0xEF && buf[(head + 1) & BUFSIZE] == 0xB0))
    {
        read();
    }
    if (size() >= 3)
    {
        return buf[(head + 2) & BUFSIZE];
    }
    return NONE;
}

#endif // COMMUNICATION_H
